package com.ttx.zookeeper.lock.raw;

import org.apache.zookeeper.ZooKeeper;

import java.util.List;
import java.util.Optional;

/**
 * 共享锁(读写锁)
 * @author TimFruit
 * @date 20-2-28 下午2:06
 */
public class SLock{

    private ZooKeeper zk;

    private String lockNodePath;

    private String readMark="read";
    private String writeMark="write";



    public SLock(ZooKeeper zk, String lockNodePath) {
        this.zk = zk;
        this.lockNodePath = lockNodePath;
    }


    public Lock readLock(){
        return new ReadLock(zk, lockNodePath, readMark);
    }

    public Lock writeLock(){
        return new WriteLock(zk, lockNodePath, writeMark);
    }






    private class ReadLock extends AbstractLock implements Lock{


        public ReadLock(ZooKeeper zk, String lockNodePath, String readMark) {
            super(zk, lockNodePath, readMark);
        }




        @Override
        protected boolean isLocked(List<String> children) {
            final String finalWriteMark=writeMark;
            boolean containWriteLock=children.stream().anyMatch(s -> s.contains(finalWriteMark));

            if(containWriteLock){
                //排在写锁之后， 需要等写操作完成
                return false;
            }

            // 当前全部都是读锁， 则获取成功
            Optional<String> opt=children.stream().filter(s -> s.startsWith(lockNodePrefix)).findFirst();
            lockNodeName=opt.orElseThrow(() -> new RuntimeException("读锁没有设置成功或者已丢失, "+lockNodePrefix));
            System.out.println("获取锁"+lockNodeName);

            return true;
        }
    }


    private class WriteLock extends AbstractLock implements Lock{


        public WriteLock(ZooKeeper zk, String lockNodePath, String writeMark) {
            super(zk, lockNodePath, writeMark);
        }


        // isLocked
        // 使用父类方法
        // 第一个子节点需要是自身设置的节点， 才算获取成功

    }


}
